package com.platform.common.utils.sql;

import java.sql.*;

/**
 * JDBC工具类
 */
public class JDBCUtil {

    private final String url;
    private final String user;
    private final String password;

    /**
     * 构造函数，初始化数据库连接信息
     *
     * @param url 数据库URL
     * @param user 用户名
     * @param password 密码
     */
    public JDBCUtil(String url, String user, String password) {
        this.url = url;
        this.user = user;
        this.password = password;
        loadDriver();
    }

    /**
     * 加载 MySQL JDBC 驱动程序
     */
    private void loadDriver() {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            System.out.println("MySQL JDBC Driver Registered!");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("MySQL JDBC Driver not found!", e);
        }
    }

    /**
     * 获取数据库连接
     *
     * @return 数据库连接对象
     * @throws SQLException 如果获取连接失败
     */
    public Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, user, password);
    }

    /**
     * 关闭数据库资源
     *
     * @param conn   数据库连接
     * @param stmt   Statement 或 PreparedStatement 对象
     * @param rs     ResultSet 对象
     */
    public static void closeResources(Connection conn, Statement stmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 执行查询语句
     *
     * @param sql 查询 SQL 语句
     * @param handler 处理查询结果的回调函数
     * @throws SQLException 如果执行查询失败
     */
    public void executeQuery(String sql, QueryHandler handler) throws SQLException {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            conn = getConnection();
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
            handler.handle(rs);
        } finally {
            closeResources(conn, stmt, rs);
        }
    }

    /**
     * 执行更新语句（INSERT, UPDATE, DELETE）
     *
     * @param sql 更新 SQL 语句
     * @return 受影响的行数
     * @throws SQLException 如果执行更新失败
     */
    public int executeUpdate(String sql) throws SQLException {
        Connection conn = null;
        Statement stmt = null;
        try {
            conn = getConnection();
            stmt = conn.createStatement();
            return stmt.executeUpdate(sql);
        } finally {
            closeResources(conn, stmt, null);
        }
    }

    /**
     * 使用 PreparedStatement 执行参数化的查询语句
     *
     * @param sql 查询 SQL 语句，带占位符 ?
     * @param params 参数数组
     * @param handler 处理查询结果的回调函数
     * @throws SQLException 如果执行查询失败
     */
    public void executePreparedQuery(String sql, Object[] params, QueryHandler handler) throws SQLException {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = getConnection();
            pstmt = conn.prepareStatement(sql);
            setParameters(pstmt, params);
            rs = pstmt.executeQuery();
            handler.handle(rs);
        } finally {
            closeResources(conn, pstmt, rs);
        }
    }

    /**
     * 使用 PreparedStatement 执行参数化的更新语句
     *
     * @param sql 更新 SQL 语句，带占位符 ?
     * @param params 参数数组
     * @return 受影响的行数
     * @throws SQLException 如果执行更新失败
     */
    public int executePreparedUpdate(String sql, Object[] params) throws SQLException {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = getConnection();
            pstmt = conn.prepareStatement(sql);
            setParameters(pstmt, params);
            return pstmt.executeUpdate();
        } finally {
            closeResources(conn, pstmt, null);
        }
    }

    /**
     * 设置 PreparedStatement 的参数值
     *
     * @param pstmt PreparedStatement 对象
     * @param params 参数数组
     * @throws SQLException 如果设置参数失败
     */
    private void setParameters(PreparedStatement pstmt, Object[] params) throws SQLException {
        if (params != null && params.length > 0) {
            for (int i = 0; i < params.length; i++) {
                pstmt.setObject(i + 1, params[i]);
            }
        }
    }

    // 定义一个接口用于处理查询结果集
    public interface QueryHandler {
        void handle(ResultSet rs) throws SQLException;
    }
}